package com.fourhats.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.RandomStringUtils;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;

import com.fourhats.dao.UserDAO;
import com.fourhats.dao.RolesDAO;
import com.fourhats.exception.UserEmailDoesNotExist;
import com.fourhats.exception.UserOldPasswordDoesNotMatch;
import com.fourhats.model.User;
import com.fourhats.model.Role;
import com.fourhats.services.UserService;
import com.fourhats.services.dto.UserDto;
import com.fourhats.services.util.Page;

public class UserServiceImpl implements UserService {

	@Autowired
	private Mapper mapper;
	
	@Autowired
	private UserDAO userDAO;
	
	@Autowired
	private RolesDAO rolesDAO;
	
	public List<UserDto> getUsersByKeyword(String keyword) {
		List<User> users = userDAO.getUsersByKeyword(keyword);
		return this.getDtos(users);
	}
	
	public Page<UserDto> getUsersPageByKeyword(String keyword, int pageNumber, int pageSize) {
		List<User> users = userDAO.getUsersByKeyword(keyword);
		return this.getPage(users, pageNumber, pageSize);
	}

	public UserDto getUserById(long userId) {
		return mapper.map(userDAO.getById(userId), UserDto.class);
	}

	public Page<UserDto> getAllUsers(int first, int maxResult) {
		List<User> users = userDAO.getAllUsers();
		return this.getPage(users, first, maxResult);
	}

	public void addUser(User newUser) {
		Role role = rolesDAO.findByName("ROLE_USER");
		newUser.setRole(role);
		userDAO.add(newUser);
	}

	public void editUser(UserDto user){
		User userToEdit = userDAO.getById(user.getId());
		userToEdit.setName(user.getName());
		userToEdit.setSurname(user.getSurname());
		userToEdit.setEmail(user.getEmail());
		userToEdit.setPhone(user.getPhone());
		userToEdit.setAddress(user.getAddress());
		userToEdit.setBirthday(user.getBirthday());
		userToEdit.setGenre(user.getGenre());
		userDAO.add(userToEdit);
	}
	
	public void updateAvatar(long userId, String avatarPath) {
		User userToEdit = userDAO.getById(userId);
		userToEdit.setAvatarPath(avatarPath);
		userDAO.add(userToEdit);
	}
	
	public void changePassword(long userId, String oldPassword, String newPassword) throws UserOldPasswordDoesNotMatch {
		User user = userDAO.getById(userId);
		if(!user.getPassword().equals(oldPassword)){
			throw new UserOldPasswordDoesNotMatch();
		}
		user.setPassword(newPassword);
		userDAO.add(user);
	}
	
	public User getByUsername(String username) {
		return userDAO.getByUsername(username);
	}

	public boolean existUser(String email) {
		return userDAO.existUser(email);
	}
	
	public String createNewPassword(String userEmail) throws UserEmailDoesNotExist {
		User user = userDAO.getByUsername(userEmail);
		if(user == null){
			throw new UserEmailDoesNotExist();
		}

		String newPassword = RandomStringUtils.randomAlphanumeric(8);
		user.setPassword(newPassword);
		userDAO.add(user);
		
		return newPassword;
	}
	
	private List<UserDto> getDtos(List<User> users) {
		List<UserDto> dtos = new ArrayList<UserDto>();
		for(User i : users) {
			dtos.add(mapper.map(i, UserDto.class));
		}
		
		return dtos;
	}
	
	@SuppressWarnings("unchecked")
	private Page<UserDto> getPage(List<User> users, int pageNumber, int pageSize) {
		int first = (pageNumber - 1) * pageSize;
		int last = pageNumber * pageSize > users.size() ? users.size() : pageNumber * pageSize;
		return (Page<UserDto>) Page.create(this.getDtos(users.subList(first, last)), pageNumber, pageSize, users.size());
	}
}